package com.gitee.cirnochat.chat.service.stragegy;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gitee.cirnochat.chat.model.vo.req.ChatMessageSendRequest;
import com.gitee.cirnochat.websocket.model.vo.resp.WebSocketMessageResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import static com.gitee.cirnochat.common.constant.RedisKey.CHAT_OFFLINE_MESSAGE;
import static com.gitee.cirnochat.common.constant.RedisConstant.CHAT_OFFLINE_MESSAGE_EXPIRE_TIME;

@Component("offlineSendStrategy")
@RequiredArgsConstructor
public class ChatMessageOfflineSendStrategy implements ChatMessageSendStrategy {

    private final StringRedisTemplate redisTemplate;
    private final ObjectMapper objectMapper;

    private static final int MAX_OFFLINE_MESSAGE_COUNT = 200;

    @Override
    public WebSocketMessageResponse sendMessage(ChatMessageSendRequest req) {
        Long receiverId = req.getSessionId();
        String redisKey = CHAT_OFFLINE_MESSAGE + receiverId;
        try {
            redisTemplate.opsForZSet().add(redisKey, objectMapper.writeValueAsString(req), req.getMessageId());
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        Long setSize = redisTemplate.opsForZSet().size(redisKey);
        if (setSize != null && setSize > MAX_OFFLINE_MESSAGE_COUNT) {
            for (int i = 0; i < setSize - MAX_OFFLINE_MESSAGE_COUNT; i++) {
                redisTemplate.opsForZSet().removeRange(redisKey, 0, 0);
            }
        }
        redisTemplate.expire(redisKey, CHAT_OFFLINE_MESSAGE_EXPIRE_TIME);
        return WebSocketMessageResponse.Builder
                .messageId(req.getMessageId())
                .message("消息已存储（离线）")
                .build();
    }
}